const fs = require('fs')
const path = require('path')

const config = require(process.cwd() + '/src/config/config')
const utils = require(process.cwd() + '/src/utils/index')

// 定义静态变量
// 所有图集资源信息
let tilesData = null

// 最基础, 最常规的构成场景的对象,大小固定为32x32
class Tile {
  constructor (src = '') {
    this.initTile(src)
  }
  
  // 初始化空的Tile对象
  initTile (src = '') {
    // 类别标识
    this.type = 'Tile'
    // 唯一性标识
    this.id = new Date().getTime() + utils.common.randomString(false, 8)
    // 该物体的四方向连通性,0-7对应:左入/上入/右入/下入/左出/上出/右出/下出
    this.pass = [true, true, true, true, true, true, true, true]
    // 该物体的视野是否可以通过,0-3对应:向左/向上/向右/向下
    this.vision = [true, true, true, true]
    // 该物体所在的层级,大于30代表置予角色层之上,固定覆盖角色
    this.layer = 10
    // 该物体的图片资源,如果该值为空,代表对象无法使用
    this.src = src
    // 该物体的动画资源
    this.animations = {}
  }
  
  // 创建动画
  createAnimation (srcList, name = 'default') {
    this.animations[name] = {
      srcList: srcList
    }
  }
  
  // 将对象中的所有资源字段变成前端可以识别的形式
  static async unzip (tile) {
    if (!Tile.tilesData) {
      await Tile.getAllTiles()
    }
    
    // src解压
    tile.src = Tile.unzipSrc(tile.src)
    
    // 动画字段中的srcList解压
    for (let key in tile.animations) {
      let obj = tile.animations[key].srcList
      const len = obj.length
      for (let i = 0; i < len; i++) {
        obj[i] = Tile.unzipSrc(obj[i])
      }
    }
  }
  
  // 将对象中所有前端可以识别的资源字段打包成id形式的资源字段
  static zip (tile) {
    // src压缩
    tile.src = Tile.zipSrc(tile.src)
    // 动画字段中的srcList压缩
    for (let key in tile.animations) {
      let obj = tile.animations[key].srcList
      const len = obj.length
      for (let i = 0; i < len; i++) {
        obj[i] = Tile.zipSrc(obj[i])
      }
    }
  }
  
  // 对于单个资源地址进行压缩,返回压缩后的地址
  static unzipSrc (src) {
    if (!src || src === '' || src.indexOf('/') >= 0) {
      // src不存在,或者src为空,或者src本身已经是解压后的地址(带有/,说明是一个路径)
      return src
    }
    
    const index = Tile.tilesData.findIndex(tile => tile.id === src)
    if (index >= 0) {
      return Tile.tilesData[index].src
    }
    return src
  }
  
  // 对于单个资源地址进行解压,返回解压后的地址
  static zipSrc (src) {
    // 匹配关键字tiles
    const SRC_MACTH = '/tile_'
    const MATCH_LEN = SRC_MACTH.length
    
    // 处理资源字符串
    const tileKeyIndex = src.indexOf(SRC_MACTH)
    if (tileKeyIndex >= 0) {
      src = src.slice(tileKeyIndex + MATCH_LEN)
      const tail = path.extname(src)
      src = path.basename(src, tail)
    }
    return src
  }
  
  // 获取所有的图集图块信息
  static async getAllTiles () {
    // 先获取所有图集文件
    const tilesetsList = await fs.promises.readdir(config.tilesetsPath)
    
    // 再读取所有图集数据
    let progressList = []
    let len = tilesetsList.length
    for (let i = 0; i < len; i++) {
      let progress = fs.promises.readFile(config.tilesetsPath + tilesetsList[i])
      progressList.push(progress)
    }
    let tilesDataArr = await Promise.all(progressList)
    
    // 取所有图集数据中有用的部分
    len = tilesDataArr.length
    let tilesData = []
    for (let i = 0; i < len; i++) {
      tilesDataArr[i] = JSON.parse(tilesDataArr[i])
      tilesDataArr[i].list = tilesDataArr[i].list.map((tile) => {
        return {
          id: tile.id,
          src: config.imagesSrcPath + tilesDataArr[i].name + '/' + tile.src
        }
      })
      tilesData = tilesData.concat(tilesDataArr[i].list)
    }
    
    Tile.tilesData = tilesData
  }
}

// 获取静态变量
Tile.tilesData = tilesData

module.exports = Tile